/*
* Conditions Of Use
*
* This software was developed by employees of the Sigmatrix(Beijing) Corporation.
* This software is provided by sigmatrix as a service and is expressly
* provided "AS IS."  Sigmatrix MAKES NO WARRANTY OF ANY KIND, EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT
* AND DATA ACCURACY.  Sigmatrix does not warrant or make any representations
* regarding the use of the software or the results thereof, including but
* not limited to the correctness, accuracy, reliability or usefulness of
* the software.
*
* Permission to use this software is contingent upon your acceptance
* of the terms of this agreement.
*
*/
package com.sigmatrix.h5.dao.impl;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import com.sigmatrix.h5.dao.OutStorageDetailDao;
import com.sigmatrix.h5.dao.impl.common.impl.BaseDaoImpl;
import com.sigmatrix.h5.dto.OutStorageDetailData;
import com.sigmatrix.h5.entity.OutStorageDetail;
import com.sigmatrix.h5.enums.OutStorageStatusEnum;
import com.sigmatrix.h5.exception.DaoException;
import com.sigmatrix.h5.utils.Cons;

/**
 *@ClassName: OutStorageDetailDaoImpl
 *@Description: 出库单详情数据库操作接口实现
 *@author youjun
 *@date 2017-06-24 17:35:21
 */
@Repository(value="outStorageDetailDao")
public class OutStorageDetailDaoImpl extends BaseDaoImpl<OutStorageDetail> implements OutStorageDetailDao {
	
	/**注入jdbcTemplate*/
	@Autowired
	private transient JdbcTemplate jdbcTemplate;
	
	/**表名*/
	public static final String TABLE_NAME = "_dealers_out_storage_detail";

	/**
	 * (non-Javadoc)
	 *@Title: findById
	 *@Description: 
	 *@see com.sigmatrix.sc.handheld.inter.dao.OutStorageDetailDao#findById(java.lang.Integer, java.lang.String)
	 *@author youjun
	 *@date 2017年7月15日 下午2:28:33
	 */
	@Override
	public OutStorageDetail findById(final Integer id, final String enterpriseCode) throws DaoException {
		final StringBuilder sql = new StringBuilder("SELECT * FROM ").append(getTname(enterpriseCode, TABLE_NAME));
		sql.append(" WHERE _id = ?");
		final Object[] params = new Object[]{id};
		final List<OutStorageDetail> list = jdbcTemplate.query(sql.toString(), params, new OutStorageDetailRowMapper());
		if(CollectionUtils.isEmpty(list)) {
			return null;
		}
		return list.get(0);
	}
	
	/**
	 * (non-Javadoc)
	 *@Title: save
	 *@Description: 
	 *@see com.sigmatrix.sc.handheld.inter.dao.OutStorageDetailDao#save(com.sigmatrix.sc.handheld.inter.entity.OutStorageDetail, java.lang.String)
	 *@author youjun
	 *@date 2017年7月15日 下午2:28:39
	 */
	@Override
	public int save(final OutStorageDetail outStorageDetail, final String enterpriseCode) throws DaoException {

		final StringBuilder sql = new StringBuilder("INSERT INTO ").append(getTname(enterpriseCode, TABLE_NAME));
		sql.append("(_out_storage_id, _order_code, _product_id, _product_code, _stock_id, _creator_id, _create_time, _actual_num, _plan_num, _code_level, _wrap_name, _is_confirm, _status, _plan_sp_num, _actual_sp_num, _fail_num, _fail_sp_num, _operate_content) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
		final Object[] params = new Object[]{outStorageDetail.getOutStorageId(), outStorageDetail.getOrderCode(), outStorageDetail.getProductId(), outStorageDetail.getProductCode(), outStorageDetail.getStockId(), outStorageDetail.getCreatorId(), outStorageDetail.getCreateTime(), outStorageDetail.getActualNum(), outStorageDetail.getPlanNum(), outStorageDetail.getCodeLevel(), outStorageDetail.getWrapName(), outStorageDetail.getIsConfirm(), outStorageDetail.getStatus(), outStorageDetail.getPlanSpNum(), outStorageDetail.getActualSpNum(), outStorageDetail.getFailNum(), outStorageDetail.getFailSpNum(), outStorageDetail.getOperateContent()};
		final int[] argTypes = new int[]{Types.BIGINT, Types.VARCHAR, Types.INTEGER, Types.VARCHAR, Types.BIGINT, Types.INTEGER, Types.TIMESTAMP, Types.INTEGER, Types.INTEGER, Types.INTEGER, Types.VARCHAR, Types.SMALLINT, Types.SMALLINT, Types.INTEGER, Types.INTEGER, Types.INTEGER, Types.INTEGER, Types.VARCHAR};
		return jdbcTemplate.update(sql.toString(), params, argTypes);
	}

	/**
	 * (non-Javadoc)
	 *@Title: update
	 *@Description: 
	 *@see com.sigmatrix.sc.handheld.inter.dao.OutStorageDetailDao#update(com.sigmatrix.sc.handheld.inter.entity.OutStorageDetail, java.lang.String)
	 *@author youjun
	 *@date 2017年7月15日 下午2:28:47
	 */
	@Override
	public int update(final OutStorageDetail outStorageDetail, final String enterpriseCode) throws DaoException {

		final StringBuilder sql = new StringBuilder("UPDATE ").append(getTname(enterpriseCode, TABLE_NAME));
		sql.append(" SET _out_storage_id = ?, _order_code = ?, _product_id = ?, _product_code = ?, _stock_id = ?, _creator_id = ?, _create_time = ?, _actual_num = ?, _plan_num = ?, _code_level = ?, _wrap_name = ?, _is_confirm = ?, _status = ?, _plan_sp_num = ?, _actual_sp_num = ?, _fail_num = ?, _fail_sp_num = ?, _operate_content = ? WHERE _id = ?");
		final Object[] params = new Object[]{outStorageDetail.getOutStorageId(), outStorageDetail.getOrderCode(), outStorageDetail.getProductId(), outStorageDetail.getProductCode(), outStorageDetail.getStockId(), outStorageDetail.getCreatorId(), outStorageDetail.getCreateTime(), outStorageDetail.getActualNum(), outStorageDetail.getPlanNum(), outStorageDetail.getCodeLevel(), outStorageDetail.getWrapName(), outStorageDetail.getIsConfirm(), outStorageDetail.getStatus(), outStorageDetail.getPlanSpNum(), outStorageDetail.getActualSpNum(), outStorageDetail.getFailNum(), outStorageDetail.getFailSpNum(), outStorageDetail.getOperateContent(), outStorageDetail.getId()};
		final int[] argTypes = new int[]{Types.BIGINT, Types.VARCHAR, Types.INTEGER, Types.VARCHAR, Types.BIGINT, Types.INTEGER, Types.TIMESTAMP, Types.INTEGER, Types.INTEGER, Types.INTEGER, Types.VARCHAR, Types.SMALLINT, Types.SMALLINT, Types.INTEGER, Types.INTEGER, Types.INTEGER, Types.INTEGER, Types.VARCHAR, Types.BIGINT};
		return jdbcTemplate.update(sql.toString(), params, argTypes);
	}
	
	/**
	 * (non-Javadoc)
	 *@Title: closeByOutStorageId
	 *@Description: 
	 *@see com.sigmatrix.sc.handheld.inter.dao.OutStorageDetailDao#closeByOutStorageId(long, java.util.List, java.lang.String)
	 *@author youjun
	 *@date 2017年8月23日 下午5:04:08
	 */
	@Override
	public int closeByOutStorageId(final long outStorageId, final List<Integer> canCloseStatusList, final String enterpriseCode) throws DaoException {

		if(StringUtils.isBlank(enterpriseCode)
				||CollectionUtils.isEmpty(canCloseStatusList)) {
			throw new DaoException("关闭出库单详情参数有误");
		}
		StringBuilder sql = new StringBuilder("UPDATE ").append(getTname(enterpriseCode, TABLE_NAME));
		sql.append(" SET _status = ? WHERE _out_storage_id = ? AND _status IN (");
		final List<Object> paramList = new ArrayList<Object>();
		paramList.add(OutStorageStatusEnum.CLOSE.getId());
		paramList.add(outStorageId);
		for(final Integer canStauts:canCloseStatusList) {
			sql.append("?").append(",");
			paramList.add(canStauts);
		}
		sql = new StringBuilder(sql.substring(0, sql.length()-1)); // 取出最后的","
		sql.append(")");
		return jdbcTemplate.update(sql.toString(), paramList.toArray());
	}
	
	/**
	 * (non-Javadoc)
	 *@Title: findListByCondition
	 *@Description: 
	 *@see com.sigmatrix.sc.handheld.inter.dao.OutStorageDetailDao#findListByCondition(com.sigmatrix.sc.handheld.inter.entity.OutStorageDetail, java.lang.String)
	 *@author youjun
	 *@date 2017年7月15日 下午2:28:54
	 */
	@Override
	public List<OutStorageDetail> findListByCondition(final OutStorageDetail outStorageDetail, final String enterpriseCode) throws DaoException {

		final StringBuilder sql = new StringBuilder("SELECT * FROM ").append(getTname(enterpriseCode, TABLE_NAME));
				final List<Object> paramList = new ArrayList<Object>();
		sql.append(" WHERE _status <> ?");
		paramList.add(Cons.STATUS_DELETE);
		try {
			// 请不要使用like
			if(outStorageDetail!=null) {
				if(outStorageDetail.getOutStorageId()!=null){
					sql.append(" AND _out_storage_id = ?");
					paramList.add(outStorageDetail.getOutStorageId());
				}
				if(outStorageDetail.getProductId()!=null){
					sql.append(" AND _product_id = ?");
					paramList.add(outStorageDetail.getProductId());
				}
			}
			return jdbcTemplate.query(sql.toString(), paramList.toArray(), new OutStorageDetailRowMapper());
		} catch (DataAccessException e) {
			throw new DaoException(e);
		}
	}
	
	/**(non-Javadoc)
	 * @throws DaoException 
	 *@Title: findPartColumnListByCondition
	 *@Description: 
	 *@see com.sigmatrix.sc.handheld.inter.dao.OutStorageDetailDao#findPartColumnListByCondition(com.sigmatrix.sc.handheld.inter.entity.OutStorageDetail)
	 *@author youjun
	 *@date 2017年6月26日 下午1:54:01
	 */
	@Override
	public List<OutStorageDetailData> findPartColumnListByCondition(final OutStorageDetail outStorageDetail, 
			final String enterpriseCode) throws DaoException {

		final StringBuilder sql = new StringBuilder("SELECT _id,_out_storage_id,_product_id,_plan_num,_actual_num,_code_level,_status FROM ");
		sql.append(getTname(enterpriseCode, TABLE_NAME));
		final List<Object> paramList = new ArrayList<Object>();
		sql.append(" WHERE _status <> ?");
		paramList.add(Cons.STATUS_DELETE);
		sql.append(assemblyWhereConditon(outStorageDetail, paramList, true));
		sql.append(" ORDER BY _out_storage_id DESC");
		try {
			return jdbcTemplate.query(sql.toString(), paramList.toArray(), new RowMapper<OutStorageDetailData>(){

				@Override
				public OutStorageDetailData mapRow(final ResultSet resultSet, final int rowNum) throws SQLException {
					final OutStorageDetailData outStorageDetail = new OutStorageDetailData();
		            outStorageDetail.setDetailId(resultSet.getInt("_id"));
					outStorageDetail.setOutStorageId(resultSet.getInt("_out_storage_id"));
					outStorageDetail.setProductId(resultSet.getInt("_product_id"));
					outStorageDetail.setPlanNum(resultSet.getInt("_plan_num"));
					outStorageDetail.setActualNum(resultSet.getInt("_actual_num"));
					outStorageDetail.setStatus(resultSet.getShort("_status"));
					outStorageDetail.setCodeLevel(resultSet.getInt("_code_level"));
		            return outStorageDetail;
				}
			});
		} catch(DataAccessException e) {
			throw new DaoException(e);
		}
	}
	
	/**
	 *@Title: assemblyWhereConditon
	 *@Description: TODO()
	 *@return String
	 *@author youjun
	 *@date 2017年6月26日 下午1:56:08
	 *@param outStorageDetail
	 *@param paramList
	 *@param isExistWhereCondition
	 *@return
	 * @throws DaoException 
	 */
	private String assemblyWhereConditon(final OutStorageDetail outStorageDetail, final List<Object> paramList, final boolean isExistWhereCondition) throws DaoException {

		if(paramList==null) {
			throw new DaoException("参数列表不能为null");
		}
		final StringBuilder whereSql = new StringBuilder();
		if(!isExistWhereCondition) {
			whereSql.append(" WHERE 1=1");
		}
		if(outStorageDetail!=null) {
			if(outStorageDetail.getProductId()!=null) {
				whereSql.append(" AND _product_id = ?");
				paramList.add(outStorageDetail.getProductId());
			}
			if(outStorageDetail.getOutStorageId()!=null) {
				whereSql.append(" AND _out_storage_id = ? ");
				paramList.add(outStorageDetail.getOutStorageId());
			}
			if(StringUtils.isNotBlank(outStorageDetail.getOrderCode())) {
				whereSql.append(" AND _order_code like ?");
				paramList.add(new StringBuilder("%").append(outStorageDetail.getOrderCode()).append("%"));
			}
		}
		return whereSql.toString();
	}
	
	/**(non-Javadoc)
	 * @throws DaoException 
	 *@Title: batchSave
	 *@Description: 
	 *@see com.sigmatrix.sc.handheld.inter.dao.OutStorageDetailDao#batchSave(java.util.List)
	 *@author youjun
	 *@date 2017年7月6日 下午1:56:49
	 */
	@Override
	public int batchSave(final List<OutStorageDetail> detailList, final String enterpriseCode) throws DaoException {

		if(CollectionUtils.isEmpty(detailList)) {
			throw new DaoException("批量更新的集合不能为空");
		}
		final StringBuilder sql = new StringBuilder("INSERT INTO ").append(getTname(enterpriseCode, TABLE_NAME));
		sql.append("(_out_storage_id, _order_code, _product_id, _product_code, _stock_id, _creator_id, _create_time, _actual_num, _plan_num, _code_level, _wrap_name, _is_confirm, _status, _plan_sp_num, _actual_sp_num, _fail_num, _fail_sp_num, _operate_content) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
		final List<Object[]> paramList = new ArrayList<Object[]>();
		for(final OutStorageDetail outStorageDetail:detailList) {
			final Object[] params = new Object[]{outStorageDetail.getOutStorageId(), outStorageDetail.getOrderCode(), outStorageDetail.getProductId(), outStorageDetail.getProductCode(), outStorageDetail.getStockId(), outStorageDetail.getCreatorId(), outStorageDetail.getCreateTime(), outStorageDetail.getActualNum(), outStorageDetail.getPlanNum(), outStorageDetail.getCodeLevel(), outStorageDetail.getWrapName(), outStorageDetail.getIsConfirm(), outStorageDetail.getStatus(), outStorageDetail.getPlanSpNum(), outStorageDetail.getActualSpNum(), outStorageDetail.getFailNum(), outStorageDetail.getFailSpNum(), outStorageDetail.getOperateContent()};
			paramList.add(params);
		}
		final int[] results = jdbcTemplate.batchUpdate(sql.toString(), paramList);
		return results[0];
	}

	/**
	 *@ClassName: OutStorageDetailRowMapper
	 *@Description: 封装返回的实体
	 *@author youjun
	 *@date 2017-06-24 17:35:21
	 */
	public class OutStorageDetailRowMapper implements RowMapper<OutStorageDetail> {
		public OutStorageDetail mapRow(final ResultSet resultSet, final int rowNum) throws SQLException {
			final OutStorageDetail outStorageDetail = new OutStorageDetail();
            outStorageDetail.setId(resultSet.getLong("_id"));
			outStorageDetail.setOutStorageId(resultSet.getLong("_out_storage_id"));
			outStorageDetail.setOrderCode(resultSet.getString("_order_code"));
			outStorageDetail.setProductId(resultSet.getInt("_product_id"));
			outStorageDetail.setProductCode(resultSet.getString("_product_code"));
			outStorageDetail.setStockId(resultSet.getLong("_stock_id"));
			outStorageDetail.setCreatorId(resultSet.getInt("_creator_id"));
			outStorageDetail.setCreateTime(resultSet.getTimestamp("_create_time"));
			outStorageDetail.setActualNum(resultSet.getInt("_actual_num"));
			outStorageDetail.setPlanNum(resultSet.getInt("_plan_num"));
			outStorageDetail.setCodeLevel(resultSet.getInt("_code_level"));
			outStorageDetail.setWrapName(resultSet.getString("_wrap_name"));
			outStorageDetail.setIsConfirm(resultSet.getShort("_is_confirm"));
			outStorageDetail.setStatus(resultSet.getShort("_status"));
			outStorageDetail.setPlanSpNum(resultSet.getInt("_plan_sp_num"));
			outStorageDetail.setActualSpNum(resultSet.getInt("_actual_sp_num"));
			outStorageDetail.setFailNum(resultSet.getInt("_fail_num"));
			outStorageDetail.setFailSpNum(resultSet.getInt("_fail_sp_num"));
			outStorageDetail.setOperateContent(resultSet.getString("_operate_content"));
            return outStorageDetail;
		} 
	}

}
